package ru.aptu.gsp_banking.service_impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.aptu.gsp_banking.dao.CurrencyDAO;
import ru.aptu.gsp_banking.dao.CurrencyInfoDAO;
import ru.aptu.gsp_banking.domain.Currency;
import ru.aptu.gsp_banking.domain.CurrencyInfo;
import ru.aptu.gsp_banking.service.CurrencyService;
import ru.aptu.gsp_banking.utils.CurrencyGrabber;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: alex
 * Date: 12/21/11
 * Time: 3:07 PM
 */

@Service
public class CurrencyServiceImpl implements CurrencyService {

    @Autowired
    private CurrencyDAO currencyDAO;

    @Autowired
    private CurrencyInfoDAO currencyInfoDAO;

    @Autowired
    private CurrencyGrabber currencyGrabber;

    @Transactional
    public void updateCurrencyIfNeeded() {
        Calendar cal = Calendar.getInstance();
        CurrencyInfo currencyInfo = currencyInfoDAO.getCurrencyInfo();

        if (currencyInfo.getUpdated().before(cal.getTime())) {
            List<Currency> currencyList = currencyDAO.listCurrency();

            List<Float> exchangeRates = new ArrayList<Float>(currencyList.size());
            exchangeRates.add(new Float(1.0));
            String nativeCurrency = currencyList.get(0).getId();
            boolean ratesUpdated = true;

            for (int i = 1; i < currencyList.size(); ++i) {
                Float exchangeRate = currencyGrabber.getExchangeRate(currencyList.get(i).getId(), nativeCurrency);
                if (exchangeRate != 0.0) {
                    exchangeRates.add(exchangeRate);
                } else {
                    ratesUpdated = false;
                    break;
                }
            }


            if (ratesUpdated) {
                Calendar c = new GregorianCalendar();
                c.setTime(cal.getTime());
                c.set(Calendar.HOUR_OF_DAY, 23);
                c.set(Calendar.MINUTE, 59);
                c.set(Calendar.SECOND, 59);
                c.getTime();
                Date updateTime = c.getTime();
                currencyInfo.setUpdated(updateTime);
                currencyInfoDAO.updateCurrencyInfo(currencyInfo);

                for (int i = 1; i < exchangeRates.size(); ++i) {
                    currencyList.get(i).setExchangeRate(exchangeRates.get(i));
                    currencyDAO.updateCurrency(currencyList.get(i));
                }
            }
        }
    }

    @Transactional
    public List<Currency> listCurrency() {
        return currencyDAO.listCurrency();
    }

    @Transactional
    public Float convert(Float amount, String currencyFromId, String currencyToId) {
        if (currencyFromId.equals(currencyToId))
            return amount;

        updateCurrencyIfNeeded();

        List<Currency> listCurrencies = listCurrency();
        Currency currencyFrom = null;
        Currency currencyTo = null;
        for (Currency currency : listCurrencies) {
            if (currency.getId().equals(currencyFromId)) {
                currencyFrom = currency;
            } else if (currency.getId().equals(currencyToId)) {
                currencyTo = currency;
            }
        }

        if (currencyFrom != null && currencyTo != null) {
            return new Float(amount * currencyFrom.getExchangeRate() / currencyTo.getExchangeRate());
        }
        return new Float(-1.0);
    }
}
